package com.fq.wechat.util;

import com.fq.wechat.controller.WeChatController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * MsgTypeInvokeUtil: 根据不同的消息类型(MsgType)进行路由转发
 * @author jifang.
 * @since 2016/4/18 16:05.
 */
public class MsgTypeInvokeUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(MsgTypeInvokeUtil.class);

    private static final Class<?> controller = WeChatController.class;

    private static final Set<String> methods;

    static {
        Method[] declaredMethods = controller.getDeclaredMethods();
        methods = new HashSet<>(declaredMethods.length);
        for (Method method : declaredMethods) {
            methods.add(method.getName());
        }
    }

    public static Object invoke(String wxMsgType, Object target, Object... args) {
        String methodName = composeMethodMame(wxMsgType);
        Class<?>[] paramTypes = new Class[args.length];
        for (int i = 0; i < args.length; ++i) {
            paramTypes[i] = args[i].getClass().getInterfaces()[0];
        }
        try {
            Method method = controller.getDeclaredMethod(methodName, paramTypes);
            method.setAccessible(true);
            return method.invoke(target, args);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            LOGGER.error("method {} invoke error", methodName, e);
            throw new RuntimeException(e);
        }
    }

    private static String composeMethodMame(String wxMsgType) {
        String prefix = wxMsgType.substring(0, 1).toUpperCase();
        String suffix = wxMsgType.substring(1).toLowerCase();
        String methodName = new StringBuilder("on").append(prefix).append(suffix).toString();
        if (!methods.contains(methodName))
            methodName = "onDefault";
        return methodName;
    }
}
